﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;

namespace Petaframe.DataAccessLayer
{
    /*
    public abstract class Repository<T> : IRepository<T> where T : class
    {
        SqlConnection _conn;
        SqlCommand _cmd;
        SqlDataAdapter _adapter;
        SqlDataReader _reader;
        IDetachedQuery _detachedQuery;

        string primaryKeyName = string.Empty;
        string tableName = typeof(T).Name;
        //string _cmdText = string.Empty;
        DynamicEntityBuilder<T> _builder;
        long maxNumberOfResults = 10000;

        public long MaxNumberOfResults
        {
            get { return maxNumberOfResults; }
            set { maxNumberOfResults = value; }
        }


        public Repository(string primaryKeyColumnName, string tableName = "")
        {
            primaryKeyName = primaryKeyColumnName;
            this.tableName = string.IsNullOrWhiteSpace(tableName) ? typeof(T).Name : tableName;
            _conn = new SqlConnection("");
            _cmd = new SqlCommand("", _conn);
            // parametersList = new List<SqlParameter>();

        }

        void OpenConnection()
        {
            var serviceConnection = this.GetType().GetCustomAttributes(typeof(ServiceConnectionNameAttribute), false)[0] as ServiceConnectionNameAttribute;
            if (serviceConnection != null)
                _conn.ConnectionString = ConfigurationManager.ConnectionStrings[serviceConnection.ConnectionName].ConnectionString;

            _conn.Open();
        }

        void CloseConnection()
        {
            _cmd.Parameters.Clear();

            _conn.Close();
        }

        public T FindBy(string selectCommand)
        {
            if (string.IsNullOrWhiteSpace(selectCommand))
                throw new ArgumentNullException("commandText");


            _cmd.CommandText = selectCommand;

            OpenConnection();

            _reader = _cmd.ExecuteReader();
            _builder = DynamicEntityBuilder<T>.CreateBuilder(_reader);
            T item = null;

            if (_reader.Read())
                item = _builder.Build(_reader);

            CloseConnection();
            return item;
        }

        public T FindByID(object id)
        {
            _cmd.CommandText = string.Format("select * from {0} where {1}={2}", tableName, primaryKeyName, id);

            OpenConnection();

            _reader = _cmd.ExecuteReader();
            _builder = DynamicEntityBuilder<T>.CreateBuilder(_reader);
            T item = null;
            if (_reader.Read())
                item = _builder.Build(_reader);

            CloseConnection();
            return item;
        }

        public IEnumerable<T> FindAll()
        {
            _cmd.CommandText = string.Format("select top {0} * from {1}", maxNumberOfResults, tableName);

            OpenConnection();
            _reader = _cmd.ExecuteReader();
            _builder = DynamicEntityBuilder<T>.CreateBuilder(_reader);
            T item = null;
            List<T> items = new List<T>();

            while (_reader.Read())
            {
                item = _builder.Build(_reader);
                items.Add(item);
            }
            CloseConnection();
            return items;
        }

        public IEnumerable<T> FindAll(string selectCommand)
        {

            if (string.IsNullOrWhiteSpace(selectCommand))
                throw new ArgumentNullException("commandText");

            _cmd.CommandText = selectCommand.Trim().Insert(6, string.Format(" top {0} ", maxNumberOfResults));



            OpenConnection();
            _reader = _cmd.ExecuteReader();
            _builder = DynamicEntityBuilder<T>.CreateBuilder(_reader);
            T item = null;
            List<T> items = new List<T>();
            while (_reader.Read())
            {
                item = _builder.Build(_reader);
                items.Add(item);
            }
            CloseConnection();
            return items;
        }

        //public IPagedResults<T> Paged(int currentPage=1, int pageSize=20,int a)
        //{

        //    var pageStart = (currentPage - 1) * pageSize;
        //    var sql = string.Format("SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY {0}) AS Row,  * FROM {1}) as Paged WHERE Row > {2} AND Row <={3}  ", primaryKeyName, tableName, pageStart, (pageStart + pageSize));

        //    IPagedResults<T> result = new PagedResults<T>();       

        //    OpenConnection();
        //    _cmd.CommandText = sql;          

        //    _reader = _cmd.ExecuteReader();
        //    _builder = DynamicEntityBuilder<T>.CreateBuilder(_reader);
        //    T item = null;
        //    List<T> items = new List<T>();
        //    while (_reader.Read())
        //    {
        //        item = _builder.Build(_reader);
        //        items.Add(item);
        //    }
        //    CloseConnection();
        //    result.items = items;
        //    return result;
        //}

        public IPagedResults<T> Paged(int currentPage = 1, int pageSize = 20, string columns = "*", string whereCommandText = "")
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("SELECT {0} FROM (SELECT ROW_NUMBER() OVER (ORDER BY {1}) AS Row,  {0} FROM {2} ", columns, primaryKeyName, tableName);

            if (!string.IsNullOrEmpty(whereCommandText))
            {
                if (!whereCommandText.Trim().StartsWith("where", StringComparison.OrdinalIgnoreCase))
                {
                    whereCommandText = "WHERE " + whereCommandText;
                }
                sb.AppendFormat(" {0} ", whereCommandText);
            }

            var pageStart = (currentPage - 1) * pageSize;

            sb.AppendFormat(") as Paged WHERE Row > {0} AND Row <={1} ", pageStart, (pageStart + pageSize));
     * 

            //var sql = string.Format("SELECT {0} FROM (SELECT ROW_NUMBER() OVER (ORDER BY {1}) AS Row,  {0} FROM {2} {3} ) as Paged WHERE Row > {4} AND Row <={5}  ",columns, primaryKeyName, tableName,whereCommandText, pageStart, (pageStart + pageSize));

            IPagedResults<T> result = new PagedResults<T>();

            OpenConnection();
            _cmd.CommandText = sb.ToString();

            _reader = _cmd.ExecuteReader();
            _builder = DynamicEntityBuilder<T>.CreateBuilder(_reader);
            T item = null;
            List<T> items = new List<T>();
            while (_reader.Read())
            {
                item = _builder.Build(_reader);
                items.Add(item);
            }
            CloseConnection();
            result.items = items;
            return result;
        }

        //TODO: en son insert edilen id döndür
        public object Insert(T item)
        {
            StringBuilder sb = new StringBuilder();
            object result = null;
            sb.Append("insert into ");
            sb.Append(tableName);
            sb.Append("(");
            var properties = typeof(T).GetProperties();

            for (int i = 1; i < properties.Count(); i++)
            {
                sb.Append(properties[i].Name);
                if (i + 1 < properties.Count())
                    sb.Append(",");
            }
            sb.Append(")");
            sb.AppendFormat(" output inserted.{0} values(", primaryKeyName);
            for (int i = 1; i < properties.Count(); i++)
            {
                var value = properties[i].GetValue(item, null);
                if (value != null)
                {
                    sb.AppendFormat(" @p{0}", i);
                    _cmd.Parameters.AddWithValue(string.Format("p{0}", i), value);
                    if (i + 1 < properties.Count())
                        sb.Append(",");
                }
            }
            sb.Append(")");
            OpenConnection();
            _cmd.CommandText = sb.ToString();
            result = _cmd.ExecuteScalar();
            CloseConnection();
            return result;
        }

        public void Update(T item)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("update {0} set ", tableName);

            var properties = typeof(T).GetProperties();

            for (int i = 1; i < properties.Count(); i++)
            {
                var value = properties[i].GetValue(item, null);

                if (value != null)
                {
                    sb.AppendFormat(" {0}=\'{1}\'", properties[i].Name, properties[i].GetValue(item, null));
                    _cmd.Parameters.AddWithValue(string.Format("p{0}", i), value);
                    if (i + 1 < properties.Count())
                        sb.Append(",");
                }
            }

            sb.AppendFormat(" where {0} =\'{1}\' ", primaryKeyName, typeof(T).GetProperty(primaryKeyName).GetValue(item, null));

            _cmd.CommandText = sb.ToString();

            OpenConnection();
            _cmd.ExecuteNonQuery();
            CloseConnection();
        }

        public void Delete(T item)
        {
            StringBuilder sb = new StringBuilder();
            var value = typeof(T).GetProperty(primaryKeyName).GetValue(item, null);
            sb.AppendFormat("delete from {0} where {1}=@p1", tableName, primaryKeyName);
            _cmd.Parameters.AddWithValue("p1", value);
            OpenConnection();
            _cmd.CommandText = sb.ToString();
            _cmd.ExecuteNonQuery();
            CloseConnection();
        }

        public IDetachedQuery DetachedQuery
        {
            get
            {
                if (_detachedQuery == null)
                    _detachedQuery = new DetachedQuery();

                return _detachedQuery;
            }
            
        }

        public void AddParameter(string parameterName, object parameterValue, SqlDbType dbType, int parameterSize)
        {
            SqlParameter p = new SqlParameter();
            p.ParameterName = parameterName;
            p.Value = parameterValue ?? DBNull.Value;
            p.SqlDbType = dbType;
            p.Size = parameterSize;
            _cmd.Parameters.Add(p);

        }

        public void AddOutputParameter(string parameterName, SqlDbType dbType, int parameterSize)
        {
            SqlParameter p = new SqlParameter();
            p.ParameterName = parameterName;
            p.Direction = ParameterDirection.Output;
            p.SqlDbType = dbType;
            p.Size = parameterSize;

            _cmd.Parameters.Add(p);

        }

        public object GetScalar(string commandText)
        {
            object result = null;
            OpenConnection();
            _cmd.CommandText = commandText;
            result = _cmd.ExecuteScalar();
            CloseConnection();

            return result;
        }





    }
     * */
}
